﻿using FastReport;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SHZY.BaseData.Entitys.Common.Dto.Artroute;
using SHZY.BaseData.Entitys.Common.Entity;
using SHZY.BaseData.Interfaces.Common;
using SHZY.ClayObject;
using SHZY.Common.Configuration;
using SHZY.Common.Core.Manager;
using SHZY.Common.Enum;
using SHZY.Common.Filter;
using SHZY.Common.Models.NPOI;
using SHZY.Common.Security;
using SHZY.DataEncryption;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Entitys.System;
using SHZY.Systems.Interfaces.System;
using SqlSugar;
using Yitter.IdGenerator;

namespace SHZY.BaseData.Common;

/// <summary>
/// 业务实现：⼯艺路线.
/// </summary>
[ApiDescriptionSettings(Tag = "BaseData", Name = "Artroute", Order = 200)]
[Route("api/Common/BaseData/[controller]")]
public class ComBaseArtrouteService : IComBaseArtrouteService, IDynamicApiController, ITransient
{
    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<ComBaseArtrouteEntity> _repository;

    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<ComBaseArtroutematerialEntity> _repositorymaterial;

    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<ComBaseArtroutedetailEntity> _repositorydetail;

    /// <summary>
    /// 多租户事务.
    /// </summary>
    private readonly ITenant _db;

    /// <summary>
    /// 数据接口服务.
    /// </summary>
    private readonly IDataInterfaceService _dataInterfaceService;

    /// <summary>
    /// 用户管理.
    /// </summary>
    private readonly IUserManager _userManager;

    /// <summary>
    /// 初始化一个<see cref="ComBaseArtrouteService"/>类型的新实例.
    /// </summary>
    public ComBaseArtrouteService(
        ISqlSugarRepository<ComBaseArtrouteEntity> qmsBaseArtrouteRepository,
        ISqlSugarRepository<ComBaseArtroutematerialEntity> qmsBaseArtroutematerialEntity,
        ISqlSugarRepository<ComBaseArtroutedetailEntity> qmsBaseArtroutedetailEntity,
        IDataInterfaceService dataInterfaceService,
        ISqlSugarClient context,
        IUserManager userManager)
    {
        _repository = qmsBaseArtrouteRepository;
        _repositorymaterial = qmsBaseArtroutematerialEntity;
        _repositorydetail = qmsBaseArtroutedetailEntity;
        _dataInterfaceService = dataInterfaceService;
        _db = context.AsTenant();
        _userManager = userManager;
    }

    /// <summary>
    /// 获取⼯艺路线.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<dynamic> GetInfo(string id)
    {
        return (await _repository.FirstOrDefaultAsync(x => x.Id == id)).Adapt<ComBaseArtrouteInfoOutput>();
    }

    /// <summary>
    /// 获取工序.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("GetDetailInfo/{id}")]
    public async Task<dynamic> GetDetailInfo(string id)
    {
        var data = await _repositorydetail.Context
            .Queryable<ComBaseArtroutedetailEntity, ComBaseModelingEntity>((a, b) => new JoinQueryInfos(JoinType.Inner, a.EnCode == b.EnCode && b.DeleteMark == null))
            .Where(a => a.ParentId == id && a.DeleteMark == null)
            .OrderBy(a => a.Sort)
            .Select((a, b) => new
            {
                id = b.Id,
                detailId = a.Id,
                enCode = b.EnCode,
                fullName = b.FullName,
                //stationCode = b.StationCode,
                stationCode=a.StationCode,
                pieceRate = a.PieceRate,
                sort = a.Sort,
                enabledMark = a.EnabledMark,
            })
            .ToListAsync();
        return data;
    }

    /// <summary>
    /// 获取工位.
    /// </summary>
    /// <returns></returns>
    [HttpGet("GetDetailStationInfo")]
    public async Task<dynamic> GetDetailStationInfo()
    {
        return await _repositorydetail.Context
            .Queryable<ComBaseStationEntity>()
            .Where(b => b.EnabledMark == 1 && b.DeleteMark == null)
            .Select(b => new
            {
                stationCode = b.EnCode,
                b.FullName,
            })
            .ToListAsync();
    }

    /// <summary>
    /// 获取物料.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("GetMaterialInfo/{id}")]
    public async Task<dynamic> GetMaterialInfo(string id)
    {
        return await _repositorymaterial.Context
            .Queryable<ComBaseArtroutematerialEntity, ComBaseMaterialEntity, DictionaryDataEntity>((a, b, c) => new JoinQueryInfos(JoinType.Inner, a.MaterialCode == b.Code, JoinType.Left, (b.Unit == c.EnCode || b.Unit.Equals(c.FullName)) && c.DictionaryTypeId.Contains("459486664230731141") && c.DeleteMark == null))
            .Where((a, b, c) => a.ParentId == id && a.DeleteMark == null)
            .Select((a, b, c) => new
            {
                id = b.Id,
                materialId = a.Id,
                code = b.Code,
                name = b.Name,
                unit = c.FullName,
                enabledMark = a.EnabledMark
            })
            .ToListAsync();
    }

    /// <summary>
    /// 获取⼯艺路线列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("")]
    public async Task<dynamic> GetList([FromQuery] ComBaseArtrouteListQueryInput input)
    {
        var data = await _repository.Context.Queryable<ComBaseArtrouteEntity>()
            .WhereIF(!string.IsNullOrEmpty(input.enCode), it => it.EnCode.Contains(input.enCode))
            .WhereIF(!string.IsNullOrEmpty(input.fullName), it => it.FullName.Contains(input.fullName))
            .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.EnCode.Contains(input.keyword) || it.FullName.Contains(input.keyword))
            .Where(it => it.DeleteMark == null)
            .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.Id)
            .Select(it => new ComBaseArtrouteListOutput
            {
                id = it.Id,
                enCode = it.EnCode,
                fullName = it.FullName,
                desc = it.Desc,
                enabledMark = SqlFunc.IIF(it.EnabledMark == 0, "停用", "正常"),
            }).OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
        return PageResult<ComBaseArtrouteListOutput>.SqlSugarPageResult(data);
    }

    /// <summary>
    /// 新建⼯艺路线.
    /// </summary>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPost("")]
    public async Task Create([FromBody] ComBaseArtrouteCrInput input)
    {
        try
        {
            // 开启事务
            _db.BeginTran();
            int errocount = 0;

            if (await _repository.AnyAsync(x => x.EnCode == input.enCode && x.DeleteMark == null))
            {
                // 回滚事务
                _db.RollbackTran();
                throw Oops.Oh(ErrorCode.COM1004);
            }

            ComBaseArtrouteCrInputDto dto = new ComBaseArtrouteCrInputDto()
            {
                enCode = input.enCode,
                fullName = input.fullName,
                desc = input.desc,
                enabledMark = input.enabledMark
            };
            var entity = dto.Adapt<ComBaseArtrouteEntity>();

            entity.Id = YitIdHelper.NextId().ToString();
            entity.CreatorTime = DateTime.Now;
            string text = App.User.FindFirst("UserId")?.Value;
            if (!string.IsNullOrEmpty(text))
            {
                entity.CreatorUserId = text;
            }

            entity.EnabledMark = !entity.EnabledMark.HasValue ? new int?(1) : entity.EnabledMark;

            //验证物料是否重复
            List<string> mater = new List<string>();
            foreach (var item in input.materiallist)
            {
                var artroutMater = await _repositorymaterial.Context.Queryable<ComBaseArtroutematerialEntity>().Where(a => a.DeleteMark == null && a.EnabledMark == 1 && a.MaterialCode == item.code).FirstAsync();
                if (mater.Contains(item.code) || artroutMater != null)
                {
                    // 回滚事务
                    _db.RollbackTran();
                    throw Oops.Oh("不可重复选择物料，重复选择物料号为：" + item.code);
                }
                mater.Add(item.code);
            }

            //验证工艺是否重复
            List<string> detail = new List<string>();
            foreach (var item in input.modelinglist)
            {
                if (mater.Contains(item.enCode))
                {
                    // 回滚事务
                    _db.RollbackTran();
                    throw Oops.Oh("不可重复选择工艺，重复选择工艺号为：" + item.enCode);
                }
                detail.Add(item.enCode);
            }

            //新增工艺信息
            int detailNum = 1;
            foreach (var item in input.modelinglist)
            {
                var itemEntity = item.Adapt<ComBaseArtroutedetailEntity>();
                itemEntity.Id = YitIdHelper.NextId().ToString();
                itemEntity.ParentId = entity.Id;
                itemEntity.Sort = detailNum;
                itemEntity.CreatorTime = DateTime.Now;
                if (!string.IsNullOrEmpty(text))
                {
                    itemEntity.CreatorUserId = text;
                }

                itemEntity.EnabledMark = !itemEntity.EnabledMark.HasValue ? new int?(1) : itemEntity.EnabledMark;
                var flg = await _repositorydetail.Context
                        .Insertable(itemEntity)
                        .IgnoreColumns(ignoreNullColumn: true)
                        .ExecuteCommandAsync();
                if (flg <= 0)
                {
                    errocount++;
                }
                detailNum++;
            }

            //新增物料信息
            foreach (var item in input.materiallist)
            {
                item.materialCode = item.code;
                var itemEntity = item.Adapt<ComBaseArtroutematerialEntity>();
                itemEntity.Id = YitIdHelper.NextId().ToString();
                itemEntity.ParentId = entity.Id;
                itemEntity.CreatorTime = DateTime.Now;
                if (!string.IsNullOrEmpty(text))
                {
                    itemEntity.CreatorUserId = text;
                }

                itemEntity.EnabledMark = !itemEntity.EnabledMark.HasValue ? new int?(1) : itemEntity.EnabledMark;
                var flg = await _repositorymaterial.Context
                        .Insertable(itemEntity)
                        .IgnoreColumns(ignoreNullColumn: true)
                        .ExecuteCommandAsync();
                if (flg <= 0)
                {
                    errocount++;
                }
            }

            var isOk = await _repository.Context
                .Insertable(entity)
                .IgnoreColumns(ignoreNullColumn: true)
                .ExecuteCommandAsync();

            if (isOk <= 0)
            {
                errocount++;
            }

            if (errocount > 0)
            {
                // 回滚事务
                _db.RollbackTran();
                throw Oops.Oh(ErrorCode.COM1000);
            }
            else
            {
                // 关闭事务
                _db.CommitTran();
            }
        }
        catch (Exception ex)
        {
            // 回滚事务
            _db.RollbackTran();
            throw Oops.Oh(ex.Message);
        }
    }

    /// <summary>
    /// 获取⼯艺路线无分页列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    private async Task<dynamic> GetNoPagingList([FromQuery] ComBaseArtrouteListQueryInput input)
    {
        return await _repository.Context.Queryable<ComBaseArtrouteEntity>()
            .WhereIF(!string.IsNullOrEmpty(input.enCode), it => it.EnCode.Contains(input.enCode))
            .WhereIF(!string.IsNullOrEmpty(input.fullName), it => it.FullName.Contains(input.fullName))
            .WhereIF(!string.IsNullOrEmpty(input.keyword), it => it.EnCode.Contains(input.keyword) || it.FullName.Contains(input.keyword))
                        .Where(it => it.DeleteMark == null)
            .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.Id)
            .Select(it => new ComBaseArtrouteListOutput
            {
                id = it.Id,
                enCode = it.EnCode,
                fullName = it.FullName,
                desc = it.Desc,
                enabledMark = SqlFunc.IIF(it.EnabledMark == 0, "关", "开"),
            }).OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort).ToListAsync();
    }

    /// <summary>
    /// 导出⼯艺路线.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("Actions/Export")]
    public async Task<dynamic> Export([FromQuery] ComBaseArtrouteListQueryInput input)
    {
        var exportData = new List<ComBaseArtrouteListOutput>();
        if (input.dataType == 0)
            exportData = Clay.Object(await GetList(input)).Solidify<PageResult<ComBaseArtrouteListOutput>>().list;
        else
            exportData = await GetNoPagingList(input);
        List<ParamsModel> paramList = "[{\"value\":\"⼯艺路线编码\",\"field\":\"enCode\"},{\"value\":\"⼯艺路线名称\",\"field\":\"fullName\"},{\"value\":\"说明描述\",\"field\":\"desc\"},{\"value\":\"有效标志\",\"field\":\"enabledMark\"},]".ToList<ParamsModel>();
        ExcelConfig excelconfig = new ExcelConfig();
        excelconfig.FileName = "⼯艺路线.xls";
        excelconfig.HeadFont = "微软雅黑";
        excelconfig.HeadPoint = 10;
        excelconfig.IsAllSizeColumn = true;
        excelconfig.ColumnModel = new List<ExcelColumnModel>();
        foreach (var item in input.selectKey.Split(',').ToList())
        {
            var isExist = paramList.Find(p => p.field == item);
            if (isExist != null)
                excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
        }

        var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
        ExcelExportHelper<ComBaseArtrouteListOutput>.Export(exportData, excelconfig, addPath);
        var fileName = _userManager.UserId + "|" + addPath + "|xls";
        return new
        {
            name = excelconfig.FileName,
            url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fileName, "SHZY")
        };
    }

    /// <summary>
    /// 批量删除⼯艺路线.
    /// </summary>
    /// <param name="ids">主键数组.</param>
    /// <returns></returns>
    [HttpPost("batchRemove")]
    public async Task BatchRemove([FromBody] List<string> ids)
    {
        var entitys = await _repository.Context.Queryable<ComBaseArtrouteEntity>().In(it => it.Id, ids).ToListAsync();
        if (entitys.Count > 0)
        {
            try
            {
                // 开启事务
                _db.BeginTran();
                int errocount = 0;

                var isOk = await _repository.Context.Updateable<ComBaseArtrouteEntity>()
                          .SetColumns(it => new ComBaseArtrouteEntity()
                          {
                              DeleteTime = DateTime.Now,
                              DeleteMark = 1,
                              DeleteUserId = _userManager.UserId
                          }).Where(it => ids.Contains(it.Id))
                          .ExecuteCommandHasChangeAsync();

                if (!isOk)
                {
                    errocount++;
                }

                var isOkdetail = await _repositorydetail.Context.Updateable<ComBaseArtroutedetailEntity>()
                              .SetColumns(it => new ComBaseArtroutedetailEntity()
                              {
                                  DeleteTime = DateTime.Now,
                                  DeleteMark = 1,
                                  DeleteUserId = _userManager.UserId
                              }).Where(it => ids.Contains(it.ParentId))
                              .ExecuteCommandHasChangeAsync();
                var isOkmaterial = await _repositorymaterial.Context.Updateable<ComBaseArtroutematerialEntity>()
                              .SetColumns(it => new ComBaseArtroutematerialEntity()
                              {
                                  DeleteTime = DateTime.Now,
                                  DeleteMark = 1,
                                  DeleteUserId = _userManager.UserId
                              }).Where(it => ids.Contains(it.ParentId))
                              .ExecuteCommandHasChangeAsync();

                if (errocount > 0)
                {
                    // 回滚事务
                    _db.RollbackTran();
                    throw Oops.Oh(ErrorCode.COM1001);
                }
                else
                {
                    // 关闭事务
                    _db.CommitTran();
                }
            }
            catch (Exception)
            {
                // 回滚事务
                _db.RollbackTran();

                throw Oops.Oh(ErrorCode.COM1002);
            }
        }
    }

    /// <summary>
    /// 更新⼯艺路线.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("{id}")]
    public async Task Update(string id, [FromBody] ComBaseArtrouteUpInput input)
    {
        try
        {
            // 开启事务
            _db.BeginTran();
            int errocount = 0;

            ComBaseArtrouteCrInputDto dto = new ComBaseArtrouteCrInputDto()
            {
                enCode = input.enCode,
                fullName = input.fullName,
                desc = input.desc,
                enabledMark = input.enabledMark
            };

            var entity = dto.Adapt<ComBaseArtrouteEntity>();
            entity.Id = input.id;
            string text = App.User.FindFirst("UserId")?.Value;

            if (!string.IsNullOrEmpty(text))
            {
                entity.CreatorUserId = text;
            }
            entity.EnabledMark = !entity.EnabledMark.HasValue ? new int?(1) : entity.EnabledMark;
            string parentId = input.id;

            //验证物料是否重复
            List<string> mater = new List<string>();
            foreach (var item in input.materiallist)
            {
                var artroutMater = await _repositorymaterial.Context.Queryable<ComBaseArtroutematerialEntity>().Where(a => a.DeleteMark == null && a.EnabledMark == 1 && a.MaterialCode == item.code && a.ParentId != parentId).FirstAsync();
                if (mater.Contains(item.code) || artroutMater != null)
                {
                    // 回滚事务
                    _db.RollbackTran();
                    throw Oops.Oh("不可重复选择物料，重复选择物料号为：" + item.code);
                }
                mater.Add(item.code);
            }

            //工艺信息
            List<string> detailIdList = new List<string>();
            int detailNum = 1;
            foreach (var item in input.modelinglist)
            {
                var itemEntity = item.Adapt<ComBaseArtroutedetailEntity>();
                if (!string.IsNullOrEmpty(item.detailId))
                {
                    itemEntity.Id = item.detailId;
                }
                itemEntity.Sort = detailNum;
                itemEntity.EnabledMark = !itemEntity.EnabledMark.HasValue ? new int?(1) : itemEntity.EnabledMark;

                if (string.IsNullOrEmpty(itemEntity.Id))
                {
                    if (!string.IsNullOrEmpty(text))
                    {
                        itemEntity.CreatorUserId = text;
                    }

                    itemEntity.Id = YitIdHelper.NextId().ToString();

                    itemEntity.ParentId = entity.Id;

                    itemEntity.CreatorTime = DateTime.Now;

                    var flg = await _repositorydetail.Context
                            .Insertable(itemEntity)
                            .IgnoreColumns(ignoreNullColumn: true)
                            .ExecuteCommandAsync();

                    if (flg <= 0)
                    {
                        errocount++;
                    }
                }
                else
                {
                    itemEntity.LastModifyTime = DateTime.Now;
                    itemEntity.LastModifyUserId = text;

                    var flg = await _repositorydetail.Context
                        .Updateable(itemEntity)
                        .UpdateColumns(it => new
                        {
                            it.EnCode,
                            it.FullName,
                            it.StationCode,
                            it.PieceRate,
                            it.Sort,
                            it.EnabledMark,
                            it.LastModifyTime,
                            it.LastModifyUserId,
                        }).ExecuteCommandAsync();

                    if (flg <= 0)
                    {
                        errocount++;
                    }
                }
                detailNum++;
                detailIdList.Add(itemEntity.Id);
            }
            if (_repositorydetail.Context.Queryable<ComBaseArtroutedetailEntity>().Where(x => !detailIdList.Contains(x.Id) && parentId == x.ParentId).ToList().Count > 0)
            {
                var deldetail = await _repositorydetail.Context.Updateable<ComBaseArtroutedetailEntity>()
                    .SetColumns(it => new ComBaseArtroutedetailEntity()
                    {
                        DeleteTime = DateTime.Now,
                        DeleteMark = 1,
                        DeleteUserId = _userManager.UserId
                    }).Where(x => !detailIdList.Contains(x.Id) && parentId == x.ParentId).ExecuteCommandHasChangeAsync();
            }

            //物料信息
            List<string> materialIdList = new List<string>();
            foreach (var item in input.materiallist)
            {
                item.materialCode = item.code;
                var itemEntity = item.Adapt<ComBaseArtroutematerialEntity>();
                if (!string.IsNullOrEmpty(item.materialId))
                {
                    itemEntity.Id = item.materialId;
                }
                itemEntity.EnabledMark = !itemEntity.EnabledMark.HasValue ? new int?(1) : itemEntity.EnabledMark;

                if (!string.IsNullOrEmpty(text))
                {
                    itemEntity.CreatorUserId = text;
                }

                if (string.IsNullOrEmpty(itemEntity.Id))
                {
                    if (!string.IsNullOrEmpty(text))
                    {
                        itemEntity.CreatorUserId = text;
                    }
                    itemEntity.Id = YitIdHelper.NextId().ToString();
                    itemEntity.ParentId = entity.Id;
                    itemEntity.CreatorTime = DateTime.Now;

                    var flg = await _repositorymaterial.Context.Insertable(itemEntity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
                    if (flg <= 0)
                    {
                        errocount++;
                    }
                }
                else
                {
                    itemEntity.LastModifyTime = DateTime.Now;
                    itemEntity.LastModifyUserId = text;

                    var flg = await _repositorymaterial.Context.Updateable(itemEntity).UpdateColumns(it => new { it.MaterialCode, it.EnabledMark, it.LastModifyTime, it.LastModifyUserId, }).ExecuteCommandAsync();
                    if (flg <= 0)
                    {
                        errocount++;
                    }
                }

                materialIdList.Add(itemEntity.Id);
            }
            if (_repositorymaterial.Context.Queryable<ComBaseArtroutematerialEntity>().Where(x => !materialIdList.Contains(x.Id) && parentId == x.ParentId).ToList().Count > 0)
            {
                var delmaterial = await _repositorymaterial.Context.Updateable<ComBaseArtroutematerialEntity>()
                    .SetColumns(it => new ComBaseArtroutematerialEntity()
                    {
                        DeleteTime = DateTime.Now,
                        DeleteMark = 1,
                        DeleteUserId = _userManager.UserId
                    }).Where(x => !materialIdList.Contains(x.Id) && parentId == x.ParentId).ExecuteCommandHasChangeAsync();
            }

            var isOk = await _repository.Context.Updateable(entity).UpdateColumns(it => new { it.EnCode, it.FullName, it.Desc, it.EnabledMark, it.LastModifyTime, it.LastModifyUserId, }).ExecuteCommandAsync();
            if (isOk <= 0)
            {
                errocount++;
            }

            if (errocount > 0)
            {
                // 回滚事务
                _db.RollbackTran();
                throw Oops.Oh(ErrorCode.COM1001);
            }
            else
            {
                // 关闭事务
                _db.CommitTran();
            }
        }
        catch (Exception ex)
        {
            // 回滚事务
            _db.RollbackTran();
            throw Oops.Oh(ErrorCode.COM1001);
        }
    }

    /// <summary>
    /// 删除⼯艺路线.
    /// </summary>
    /// <returns></returns>
    [HttpDelete("{id}")]
    public async Task Delete(string id)
    {
        try
        {
            // 开启事务
            _db.BeginTran();
            int errocount = 0;

            var isOk = await _repository.Context.Updateable<ComBaseArtrouteEntity>()
                      .SetColumns(it => new ComBaseArtrouteEntity()
                      {
                          DeleteTime = DateTime.Now,
                          DeleteMark = 1,
                          DeleteUserId = _userManager.UserId
                      }).Where(x => x.Id == id)
                      .ExecuteCommandHasChangeAsync();

            if (!isOk)
            {
                errocount++;
            }

            if (_repositorydetail.Context.Queryable<ComBaseArtroutedetailEntity>().Where(x => id == x.ParentId).ToList().Count > 0)
            {
                var isOkdetail = await _repositorydetail.Context.Updateable<ComBaseArtroutedetailEntity>()
                          .SetColumns(it => new ComBaseArtroutedetailEntity()
                          {
                              DeleteTime = DateTime.Now,
                              DeleteMark = 1,
                              DeleteUserId = _userManager.UserId
                          }).Where(x => x.ParentId == id)
                          .ExecuteCommandHasChangeAsync();
            }
            if (_repositorymaterial.Context.Queryable<ComBaseArtroutematerialEntity>().Where(x => id == x.ParentId).ToList().Count > 0)
            {
                var isOkmaterial = await _repositorymaterial.Context.Updateable<ComBaseArtroutematerialEntity>()
                          .SetColumns(it => new ComBaseArtroutematerialEntity()
                          {
                              DeleteTime = DateTime.Now,
                              DeleteMark = 1,
                              DeleteUserId = _userManager.UserId
                          }).Where(x => x.ParentId == id)
                          .ExecuteCommandHasChangeAsync();
            }

            if (errocount > 0)
            {
                // 回滚事务
                _db.RollbackTran();
                throw Oops.Oh(ErrorCode.COM1001);
            }
            else
            {
                // 关闭事务
                _db.CommitTran();
            }
        }
        catch (Exception ex)
        {
            // 回滚事务
            _db.RollbackTran();
            throw Oops.Oh(ErrorCode.COM1002);
        }
    }

    /// <summary>
    /// 获取客户类型列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("getMaterialList")]
    public async Task<dynamic> GetMaterialList()
    {
        var data = await _repository.Context.Queryable<ComBaseMaterialEntity>()
        .Where(it => it.DeleteMark == null)
        .Select(it => new
        {
            it.Id,
            it.Code,
            it.Name,
            it.Unit,
            it.Specification
        }).ToListAsync();
        return data;
    }

    /// <summary>
    /// 工艺路线下拉框（树形）.
    /// </summary>
    /// <returns></returns>
    [HttpGet("Selector/{materialCode}")]
    public async Task<dynamic> GetSelector(string materialCode)
    {
        var artroutematerialList = await _repository.Context.Queryable<ComBaseArtroutematerialEntity>()
               .Where(x => x.MaterialCode == materialCode && x.DeleteMark == null && x.EnabledMark == 1)
               .Select(x => x.ParentId).ToListAsync();

        var q1 = _repository.Context.Queryable<ComBaseArtrouteEntity>()
            .Where(x => x.DeleteMark == null && x.EnabledMark == 1)
            .WhereIF(!materialCode.Equals("0"), x => artroutematerialList.Contains(x.Id))
            .OrderBy(x => x.CreatorTime, OrderByType.Desc)
            .Select(x => new ComBaseArtrouteSelectorOutput { id = x.Id, parentId = "", enCode = x.EnCode, fullName = x.FullName });

        var q2 = _repository.Context.Queryable<ComBaseArtroutedetailEntity>()
            .Where(x => x.DeleteMark == null && x.EnabledMark == 1)
            .WhereIF(!materialCode.Equals("0"), x => artroutematerialList.Contains(x.ParentId))
            .OrderBy(x => x.CreatorTime, OrderByType.Desc)
            .Select(x => new ComBaseArtrouteSelectorOutput { id = x.Id, parentId = x.ParentId, enCode = x.EnCode, fullName = x.FullName });
        var data = await _repository.Context.UnionAll(q1, q2).ToListAsync();
        return new { list = data.ToTree("-1") };
    }
}